<?php

namespace App\Task;

use App\Model\Applet;
use App\Model\AppletPlayletRel;
use App\Model\Playlet;
use App\Model\PlayletEpisodes;
use GuzzleHttp\Client;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;

class DyVodTask
{
    protected LoggerInterface $logger;

    public static $getTokenUrl = "https://open.douyin.com/oauth/client_token/";

    public static $getVideoUrl = "https://open.douyin.com/api/playlet/v2/video/query/";

    public function __construct(protected LoggerFactory $loggerFactory)
    {
        $this->logger = $this->loggerFactory->get('log', 'dyvod');
    }

    public function execute()
    {
//        return;
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------开始定时获抖音的数据');
        $this->logger->info('获取短剧视频中需要查询任务的数据');
        //获取需要获取任务的视频
        $playletEpisodesData = PlayletEpisodes::query()->select(['id','media_id','task_id','media_status','is_dy_upload'])->where(['is_dy_upload' => 2])->where('open_video_id','!=',0)->get();

        if($playletEpisodesData->isNotEmpty()){
            $playletEpisodesIds = array();
            foreach ($playletEpisodesData as $playletEpisodesDatum){
                $playletEpisodesIds[] = $playletEpisodesDatum->id;
            }
            $playletEpisodesData = PlayletEpisodes::query()->whereIn('id',$playletEpisodesIds)->get();
            $playletIds = array();
            if(!empty($playletEpisodesData)){
                $playletIds = PlayletEpisodes::query()->whereIn('id',$playletEpisodesIds)->pluck('playlet_id');

            }

            if(!empty($playletIds)){
                $this->logger->info('获取对应的短剧的数据,短剧ID,',$playletIds->toArray());
                $playletData =  Playlet::query()->whereIn('id',$playletIds)->select(['id','name'])->get();
                $playletKeyVal = [];
                if($playletData->isNotEmpty()){
                    $playletIds = array();
                    foreach ($playletData as $playletDatum){
                        $playletKeyVal[$playletDatum->id] = $playletDatum->name;
                        $playletIds[] = $playletDatum->id;
                    }
                    //查询关联表中的抖音小程序ID
                    $this->logger->info('查询关联表中的抖音小程序ID,',$playletIds);
                    $appletPlayletRelData = AppletPlayletRel::query()->whereIn('playlet_id',$playletIds)->where(['applet_id' => 20000])->select(['playlet_id','applet_id'])->get();
                    if($appletPlayletRelData->isNotEmpty()){
                        $appletIds = array();
                        $appletPlayletKeyVal = array();
                        //遍历获取对应关系和抖音小程序ID
                        foreach ($appletPlayletRelData as $appletPlayletRelDatum){

                            $appletPlayletKeyVal[$appletPlayletRelDatum->playlet_id][] = $appletPlayletRelDatum->applet_id;
                            $appletIds[] = $appletPlayletRelDatum->applet_id;

                        }
                        $appletIds = array_values(array_unique($appletIds));
                        //查询抖音小程序的ID 获取appID 和密钥
                        $this->logger->info('查询抖音小程序的ID 获取appID 和密钥');
                        $appletData = Applet::query()->whereIn('id',$appletIds)->where(['type' => 2])->select(['id','name','app_id','app_secret'])->get();
                        if($appletData->isNotEmpty()) {
                            $appletKeyVal = [];
                            foreach ($appletData as $appletDatum) {
                                $appletKeyVal[$appletDatum->id] = $appletDatum;
                            }
                            $this->logger->info('开始遍历获取短剧剧集集数的open_video_id');
                            foreach ($playletEpisodesData as $playletEpisodes){
                                $playlet_number_name = $playletEpisodes->playlet_number_name;
                                if(!empty($playletKeyVal[$playletEpisodes->playlet_id])){
                                    //短剧名称
                                    $playlet_name = $playletKeyVal[$playletEpisodes->playlet_id];
                                    //获取对应的抖音小程序accessToken
                                    //获取这个短剧绑定的抖音小程序
                                    $appletPlayletData = $appletPlayletKeyVal[$playletEpisodes->playlet_id];
                                    $appletInfo = array();
                                    foreach ($appletPlayletData as $appletPlayletDatum){
                                        if(!empty($appletKeyVal[$appletPlayletDatum])){
                                            $appletInfo = $appletKeyVal[$appletPlayletDatum];
                                            break;
                                        }
                                    }
                                    if(!empty($appletInfo)){
                                        $applet_name = $appletInfo->name;
                                        $this->logger->info('获取绑定此短剧的抖音小程序token:'.$applet_name);
                                        $accessToken = $this->getDyAccessToken($appletInfo->id,$appletInfo->app_id,$appletInfo->app_secret);
                                        if(!empty($accessToken)){

                                            $this->logger->info('抖音小程序：'.$applet_name.' 短剧：'.$playlet_name.' 获取剧集的抖音平台ID '.$playletEpisodes->open_video_id);
                                            $videoInfo = $this->getVideoInfo($playletEpisodes->open_video_id,$appletInfo->app_id,$accessToken);
                                            if(!empty($videoInfo)){

                                                if(!empty($videoInfo['dy_cloud_id']) && $videoInfo['status'] == "OK"){
                                                    $dy_cloud_id = $videoInfo['dy_cloud_id'];
                                                    $playletEpisodes->dy_cloud_id = $dy_cloud_id;
                                                    $playletEpisodes->is_dy_upload = 3;
                                                    $playletEpisodes->save();
                                                }else{
                                                    if($videoInfo['status'] == 'INIT'){
                                                        $this->logger->info('抖音小程序：'.$applet_name.' 短剧：'.$playlet_name.' 获取抖音视频成功，视频初始化 errmsg: '.$videoInfo['status']);
                                                    }else{
                                                        $playletEpisodes->is_dy_upload = 4;
                                                        $playletEpisodes->save();
                                                        $this->logger->info('抖音小程序：'.$applet_name.' 短剧：'.$playlet_name.' 获取抖音视频失败 status状态为'.$videoInfo['status']);
                                                    }
                                                }
                                            }
                                        }else{
                                            $this->logger->error('抖音小程序:'.$applet_name.' 短剧:'.$playlet_name.' 没有对应的token');
                                        }
                                    }else{
                                        $this->logger->error('短剧:'.$playlet_name.' 没有任何绑定的抖音小程序');
                                    }
                                }else{
                                    $this->logger->error('集数ID:'.$playletEpisodes->id.' 没有对应短剧不存在');
                                }
                            }
                        }else{
                            $this->logger->error('查询抖音小程序的ID 获取appID 和密钥：没有对应的抖音小程序数据');
                        }
                    }else{
                        $this->logger->error('查询关联表中的抖音小程序ID：没有对应的短剧数据');
                    }
                }else{
                    $this->logger->error('获取对应的短剧的数据：没有对应的短剧数据');
                }
            }else{
                $this->logger->error('获取对应的短剧的Ids失败：没有对应的短剧ID');
            }
        }else{

            $this->logger->info('没有短剧集数需要查询任务');
        }
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取抖音视频数据');
    }

    public function getDyAccessToken($applet_id,$app_id,$app_secret){

        $container = ApplicationContext::getContainer();

        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('dy');

        $key = 'dy_admin_access_token';
        $key .= $applet_id;
        $accessToken = $redis->get($key);
        if(empty($accessToken)){
            $params         = [
                'grant_type' => 'client_credential',
                'client_key'    => $app_id,
                'client_secret'   => $app_secret
            ];
            //获取token
            $accessTokenInfo     = $this->request($params, self::$getTokenUrl,'POST');
            if (!empty($accessTokenInfo['data']['access_token'])){
                $accessToken = $accessTokenInfo['data']['access_token'];
                $redis->setex($key,7100,$accessToken);
            }else{
                $accessToken = "";
            }
        }
        $this->logger->info('抖音token为：'.$accessToken);
        return $accessToken;
    }

    public function getVideoInfo($open_video_id,$ma_app_id,$accessToken){

        $params         = [
            "video_id_type" => 1,
            "ma_app_id" => $ma_app_id,
            "open_video_id"    => $open_video_id,
        ];
        $taskUrl = self::$getVideoUrl;
        $this->logger->info('请求任务数据：'.PHP_EOL.var_export(['result' => $params], true));
        $this->logger->info('请求任务Url：'.$taskUrl);
        //开始上传
        $postResult  = $this->request($params, $taskUrl,'POST',$accessToken);
        if($postResult['err_no'] == 0){
            $this->logger->info('调用视频详情接口成功 返回数据：'.PHP_EOL.var_export(['result' => $postResult], true));
            return $postResult['data'];
        }else{
            $this->logger->error('调用视频详情失败 返回数据：'.PHP_EOL.var_export(['result' => $postResult], true));
        }
        return false;

    }
    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method,string $access_token = null)
    {
        $client   = new Client([
            'timeout' => 3
        ]);
        $headers       = ['Content-Type' => 'application/json'];
        if(!empty($access_token)){
            $headers['access-token'] = $access_token;
        }

        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['json'] = $params;//json_encode($params,JSON_UNESCAPED_UNICODE);
        }
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }
}